#include "kernel.h"
#include "util.h"
#include "event.h"
#include "malloc.h"


/**
 * \file event.c
 * \author Clecio Varjao and Leanne Ross
 * \date October 2007
 * \remarks Based on code created by Dr. Mantis Cheng
 * \brief RTOS event implementation
 */



EVENT *Event_Init(void){	
	EVENT *newEvent;

	Disable_Interrupt();
	newEvent=event_alloc();			// allocate space for the new event
	Enable_Interrupt();

	return newEvent;
}

void Event_Wait( EVENT *e ){
	TASK_EXECUTER *t;
	QUEUE *q;

	Disable_Interrupt();
	t=(TASK_EXECUTER*)curTE;		// set *t = the pointer to the current Task_Executer

	if (t->level==PERIODIC){		// periodic events cannot wait
		OS_Error(211);
	} else {	
		q=e->queue;
		enqueue((QUEUE*)q, t);
		kernel_wait_task(t);		// set state to waiting, if RR, remove from RR queue
	}
	Enable_Interrupt();
}

void Event_Signal( EVENT *e ){
	TASK_EXECUTER *t;
	QUEUE *q;

	Disable_Interrupt();
	q=e->queue;
	t=(TASK_EXECUTER*)dequeue((QUEUE*)q);
	if (t!=NULL){								// signal first waiting task
		kernel_signal_task(t);
	}
	Enable_Interrupt();	
}

void Event_Broadcast( EVENT *e ){
	TASK_EXECUTER *t;

	Disable_Interrupt();
	t=(TASK_EXECUTER*)dequeue((QUEUE*)&(e->queue));
	while(t!=NULL){										// signal all waiting tasks
		t->task->state = READY;
		t=(TASK_EXECUTER*)dequeue((QUEUE*)&(e->queue));
	}
	Enable_Interrupt();	
}

void  Signal_And_Next( EVENT *e ){	
	Event_Signal(e);
	Task_Next();
}

void  Broadcast_And_Next( EVENT *e ){
	Event_Broadcast(e);
	Task_Next();
}
